package com.you.weixinpay.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.you.weixinpay.domain.entity.TOrderInfo;
import com.you.weixinpay.domain.entity.TRefundInfo;
import com.you.weixinpay.enums.OrderStatus;
import com.you.weixinpay.enums.PaymentType;
import com.you.weixinpay.properties.AliPayProperties;
import com.you.weixinpay.result.Result;
import com.you.weixinpay.service.AliPayService;
import com.you.weixinpay.service.TOrderInfoService;
import com.you.weixinpay.service.TRefundInfoService;
import com.you.weixinpay.utils.AliPayNativeUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class AliPayServiceImpl implements AliPayService {
    @Autowired
    private TOrderInfoService orderInfoService;
    @Resource
    private AliPayProperties aliPayProperties;
    @Resource
    private AlipayClient alipayClient; //在【AliPayConfig】配置类中已经初始化
    @Resource
    private AliPayNativeUtils aliPayNativeUtils;

    @Resource
    private TRefundInfoService refundInfoService;

    private final ReentrantLock lock = new ReentrantLock();

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String tradeCreate(Long productId) {
        try {
            log.info("生成支付宝订单");
            Long userId = 1L;
            TOrderInfo orderInfo = orderInfoService.createOrderByProductId(productId, PaymentType.ALIPAY.getType(), userId);

            BigDecimal total = new BigDecimal(orderInfo.getTotalFee().toString());
            return aliPayNativeUtils.createPayment(orderInfo.getOrderNo(), total, orderInfo.getTitle());

        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("创建支付交易失败");
        }
    }

    @Override
    public void processOrder(Map<String, String> params) {
        log.info("处理订单");

        //获取订单号
        String orderNo = params.get("out_trade_no");

         /*在对业务数据进行状态检查和处理之前，
        要采用数据锁进行并发控制，
        以避免函数重入造成的数据混乱*/
        //尝试获取锁：
        // 成功获取则立即返回true，获取失败则立即返回false。不必一直等待锁的释放
        if(lock.tryLock()) {
            try {
                //处理重复通知
                //接口调用的幂等性：无论接口被调用多少次，以下业务执行一次
                String orderStatus = orderInfoService.getOrderStatus(orderNo);
                if (!OrderStatus.NOTPAY.getType().equals(orderStatus)) {
                    return;
                }
                //更新订单状态
                orderInfoService.updateStatusByOrderNo(orderNo,OrderStatus.SUCCESS.getType());

            } finally {
                //要主动释放锁
                lock.unlock();
            }
        }
    }

    @Override
    public Result<String> cancelOrder(String orderNo) throws AlipayApiException {

        // 1. 查询订单状态
        TOrderInfo order = orderInfoService.getOne(new LambdaQueryWrapper<TOrderInfo>()
                .eq(TOrderInfo::getOrderNo, orderNo));
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 检查订单状态是否可以取消
        if (!OrderStatus.NOTPAY.getType().equals(order.getOrderStatus())) {
            throw new RuntimeException("当前订单状态不允许取消");
        }

        //3. 调用支付宝关单接口
        aliPayNativeUtils.closeOrder(orderNo);

        // 4. 更新本地订单状态为已取消
        order.setOrderStatus(OrderStatus.CANCEL.getType());
        orderInfoService.updateById(order);

        log.info("订单取消成功，订单号：{}", orderNo);
        return Result.success();
    }

    @Override
    public String queryOrder(String orderNo) {
        try {
            return aliPayNativeUtils.queryOrder(orderNo);
        } catch (AlipayApiException e) {
            log.error("查询支付宝订单失败，订单号：{}", orderNo, e);
            throw new RuntimeException("查询订单失败", e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void refund(String orderNo, String reason) {
        log.info("调用退款API");

        //创建退款单
        TRefundInfo refundInfo = refundInfoService.createRefundByOrderNo(orderNo, reason);
        BigDecimal refundAmount = new BigDecimal(refundInfo.getRefund().toString());

        // 调用退款工具类
        AlipayTradeRefundResponse result = aliPayNativeUtils.refund(orderNo, refundAmount, reason);
        boolean refundSuccess = aliPayNativeUtils.processRefundResponse(result);

        // 更新订单状态
        OrderStatus status = refundSuccess ? OrderStatus.REFUND_SUCCESS : OrderStatus.REFUND_ABNORMAL;
        orderInfoService.updateStatusByOrderNo(orderNo, status.getType());

        //保存退款单
        refundInfo.setRefundStatus(status.getType());
        refundInfo.setContentNotify(result.getBody());
        refundInfoService.updateById(refundInfo);

    }

    @Override
    public String queryRefund(String orderNo) {
        return aliPayNativeUtils.queryRefund(orderNo);
    }


}
